/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package simple;

import algorithm.AlgorithmErrorException;
import algorithm.MultiOperator;
import algorithm.BreedingSelector;
import algorithm.PopulationBreeder;
import algorithm.Environment;
import algorithm.Individual;
import algorithm.Population;

/**
 *
 * @author Pierre
 */
public class DefaultPopulationBreeder implements PopulationBreeder {

    private BreedingSelector selector;
    private MultiOperator operator;

    public DefaultPopulationBreeder(BreedingSelector selector, MultiOperator operator) {
        this.selector = selector;
        this.operator = operator;
    }

    public Individual[] crossTwoIndividuals(Population population1, Population population2, Environment environment) throws AlgorithmErrorException {
        try {
            Individual i1 = selector.select(population1, environment);
            Individual i2 = selector.select(population2, environment);
            return operator.operate(new Individual[]{i1, i2});
        } catch (Exception e) {
            throw new AlgorithmErrorException("Error creating indiviuals", e);
        }
    }

    public Population createNewPopulation(Population population1, Population population2, Environment environment, int size) throws AlgorithmErrorException {
        if (population1.getClass() != population2.getClass()) {
            throw new AlgorithmErrorException("Cannot cross diffent population types.");
        }
        Population ret = Factory.createPopulation(population1.getClass());
        while (ret.getSize() < size) {
            Individual[] newIndividuals = crossTwoIndividuals(population1, population2, environment);
            for (Individual ind : newIndividuals) {
                if (ret.getSize() < size) {
                    ret.add(ind);
                }
            }
        }
        return ret;
    }

}
